package sim;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import org.magnos.steer.Vector;
import org.magnos.steer.spatial.SearchCallback;
import org.magnos.steer.spatial.SpatialDatabase;
import org.magnos.steer.spatial.SpatialEntity;
import org.magnos.steer.spatial.quad.SpatialQuadTree;

import ui.Grafikobjekt;
import world.Futterhaufen;
import animal.Ameise;

public class Index {
	private Logger logger = Logger.getLogger(Index.class.getName());
	private SpatialDatabase sp;
	private List<AntSimEntity> movableEntities;
	public Index(int rows,int cols){
		sp =  new SpatialQuadTree( 0, 0, rows,cols, 20000, 20 );	
		sp.refresh();
		movableEntities = new ArrayList<AntSimEntity>();
	}
	
	public void updateIndex(){
		for(AntSimEntity entity : movableEntities){
			entity.update();
		}
		sp.refresh();			
	}
	
	public void updateFoodSourcesVisibility(List<Futterhaufen> foodLocations, float dist){
		float maxVisibility = dist;
		for(final Futterhaufen location : foodLocations){			
			sp.intersects(new Vector((float)location.getX(),
									 (float)location.getY()),
									 maxVisibility,1000,3L, new SearchCallback() {				
				@Override
				public boolean onFound(SpatialEntity entity, float overlap, int index,
						Vector queryOffset, float queryRadius, int queryMax,
						long queryGroups) {
					//notify ant of food source
					Grafikobjekt gobj = ((AntSimEntity)entity).getRef();
					if(gobj instanceof Ameise) {
						((Ameise)gobj).getAntSense().detectedFoodSource = location;
					}
					return true;
				}
			});
		}
	}
	
	public void getEnemies(Vector p, float dist){
		sp.intersects(p, dist, 100, 2L,new SearchCallback() {
			
			@Override
			public boolean onFound(SpatialEntity entity, float overlap, int index,
					Vector queryOffset, float queryRadius, int queryMax,
					long queryGroups) {
				System.out.println("enemy");
				return false;
			}
		});
	}
	
	public AntSimEntity getClosePrey(Vector p, float dist, long group){
		int maxEnts = 1;
		AntSimEntity[] nearest = new AntSimEntity[maxEnts];
		float[] distances = new float[maxEnts];
		int neighbours = sp.knn(p, maxEnts, group, nearest, distances);		
		if(neighbours>0&&distances[0]<=dist){
			return nearest[0];
		}
		return null;
	}
	
	public void getCloseObjects(Vector p,float dist){
		int maxEnts = 10;
		SpatialEntity[] nearest = new SpatialEntity[maxEnts];
		float[] distances = new float[maxEnts];
		long t0 = System.currentTimeMillis();
		//sp.knn(p, maxEnts, 42, nearest, distances);
		sp.intersects(p,dist,10,1L, new SearchCallback() {			
			@Override
			public boolean onFound(SpatialEntity entity, float overlap, int index,
					Vector queryOffset, float queryRadius, int queryMax,
					long queryGroups) {
				//System.out.println("found:"+overlap+"=>"+entity);
				return true;
			}
		});		
	}
	
	public void addMovableEntity(AntSimEntity entity){
		sp.add(entity);
		movableEntities.add(entity);
	}
	
	public void removeMovableEntity(AntSimEntity entity){
		//TODO make entity inert, perhaps?
	}	
}
